var nodeTextStyleClassNormal = "spanNode1";
var nodeTextStyleClassOver = "spanNode2";
var nodeTextStyleClassFocus = "spanNode3";

function TreeNode(id,name,parentId,icon,method,enable){
	this.id = id ;
	this.name = name ;
	this.parentId = parentId ;
	this.parentNode = null ;
	this.icon = icon ;
	this.method = method==null?"":method ;
	this.enable = enable ;
	this.rank = 0 ;
	this.sequence = 0 ;
	this.subSequence = 0 ;
	this.chapterNo = '';
	this.children = new ArrayList();
	this.lines = new Array();
	this.shadowIndex = 0 ;
	this.focused = false ;
	this.opened = false ;
	this.display = false ;
	this.styleClass = nodeTextStyleClassNormal ;
	return this ;
}

TreeNode.prototype.toString = function(){
	return "id:"+this.id+",name:"+this.name+",parentId:"+this.parentId;
}

TreeNode.prototype.refreshDisplay = function(){
	var node = this.parentNode ;
	while(true){
		if(node == null){
			this.display = true ;
			return ;
		}
		if(node.opened == false){
			this.display = false ;
			return ;
		}
		node = node.parentNode ;
	}
}

TreeNode.prototype.isAncestorOf = function(node){
	if(node.parentNode == null){
		return false ;
	}
	if(node.parentId == this.id){
		return true ;
	}
	return this.isAncestorOf(node.parentNode);
}

TreeNode.prototype.getTextNodeCss = function(){
	if(this.focused){
		return nodeTextStyleClassFocus ;
	}
	return nodeTextStyleClassNormal ;
}

TreeNode.prototype.refreshDegree = function(){
	if(this.parentNode == null){
		this.rank = 0 ;
	}else{
		this.rank = this.parentNode.rank + 1 ;
	}
	this.lines = new Array(this.rank);
	if(this.children == null || this.children.size() == 0){
		return ;
	}else {
		for(var i=0;i<this.children.size();i++){
			var c = this.children.get(i) ;
			c.subSequence = i ;
			c.refreshDegree();
		}
	}
}

TreeNode.prototype.refreshChapterNo = function(){
	if(this.parentNode == null){
		this.chapterNo = "" ;
	}else{
		var temp = this.parentNode.chapterNo ;
		if(temp == ''){
			this.chapterNo =  this.subSequence + 1 ;
		}else{
			this.chapterNo =  temp + "." + (this.subSequence+1) ;
		}
	}
}

TreeNode.prototype.canMoveLeft = function(){
	if(this.parentNode == null){
		return false ;
	}
	if(this.parentNode.parentNode == null){
		return false ;
	}
	return true ;
}

TreeNode.prototype.moveLeft = function(){
	if(this.parentNode == null){
		alert('�ڵ� ['+this.name+'] ��������!');
		return ;
	}
	var grandPa = this.parentNode.parentNode ;
	if(grandPa == null){
		alert('�ڵ� ['+this.name+'] ��������!');
		return ;
	}
	this.parentNode.removeChildAt(this.subSequence) ;
	grandPa.addChild(this);
}

TreeNode.prototype.canMoveRight = function(){
	return this.hasElderBrother();
}

TreeNode.prototype.moveRight = function(){
	var elderBrother = this.preSibling();
	if(elderBrother == null){
		alert('�ڵ� ['+this.name+'] ��������!');
		return ;
	}
	this.parentNode.removeChildAt(this.subSequence) ;
	elderBrother.addChild(this);
}

TreeNode.prototype.canMoveUp = function(){
	return this.hasElderBrother();
}

TreeNode.prototype.moveUp = function(){
	var elderBrother = this.preSibling();
	if(elderBrother == null){
		alert('�ڵ� ['+this.name+'] ��������!');
		return ;
	}
	this.parentNode.changeChild(this.subSequence,elderBrother.subSequence);
}

TreeNode.prototype.canMoveDown = function(){
	return this.hasYoungerBrother();
}

TreeNode.prototype.moveDown = function(){
	var youngerBrother = this.nextSibling();
	if(youngerBrother == null){
		alert('�ڵ� ['+this.name+'] ��������!');
		return ;
	}
	this.parentNode.changeChild(this.subSequence,youngerBrother.subSequence);
}

TreeNode.prototype.addChild = function(childNode){
	childNode.subSequence = this.children.size() ;
	childNode.parentId = this.id ;
	childNode.parentNode = this ;
	childNode.rank = this.rank + 1 ;
	childNode.lines = new Array(childNode.rank);
	this.children.add(childNode);
}

TreeNode.prototype.hasChild = function(){
	return this.children.size() > 0 ;
}

TreeNode.prototype.getChildAt = function(index){
	if(this.children.size() > index){
		return this.children.get(index);
	}
	return null ;
}

TreeNode.prototype.removeChild = function(child){
	child.parentNode = null ;
	child.parentId = null ;
	this.children.remove(index);
}

TreeNode.prototype.removeChildAt = function(index){
	var child = this.getChildAt(index);
	if(child == null){
		return ;
	}
	this.removeChild(child);
}

TreeNode.prototype.removeChild = function(child){
	child.parentNode = null ;
	child.parentId = null ;
	this.children.remove(child.subSequence);
}

TreeNode.prototype.changeChild = function(index1,index2){
	var child1 = this.getChildAt(index1);
	var child2 = this.getChildAt(index2);
	child1.subSequence = index2 ;
	child2.subSequence = index1 ;
	this.children.set(index1,child2);
	this.children.set(index2,child1);
}

TreeNode.prototype.preSibling = function(){
	if(this.parentNode == null){
		return null ;
	}
	if(this.subSequence == 0){
		return null ;
	}
	return this.parentNode.children.get(this.subSequence - 1) ;
}

TreeNode.prototype.nextSibling = function(){
	if(this.parentNode == null){
//		debug(this.name+" parent node is null");
		return null ;
	}
	if(this.parentNode.children.size() <= (this.subSequence + 1)){
//		debug(this.name+" sub sequence is "+this.subSequence+" , parent node children size is "+this.parentNode.children.size());
		return null ;
	}
	return this.parentNode.children.get(this.subSequence + 1) ;
}

TreeNode.prototype.hasYoungerBrother = function(){
	return this.nextSibling() != null ;
}

TreeNode.prototype.hasElderBrother = function(){
	return this.subSequence > 0 ;
}

function Tree(rootId,rootName,rootIcon){
	this.root = new TreeNode(rootId,rootName,null,rootIcon) ;
	this.nodes = new ArrayList();
	this.nodes.add(this.root);
	this.pointer = null ;
	this.neatened = false ;
	return this ;
}

Tree.prototype.reset = function(){
	this.pointer = null ;
}

Tree.prototype.next = function(){
	if(this.pointer == null){
		this.pointer = this.root ;
	}else{
		if(this.pointer.children.size() > 0){
			this.pointer = this.pointer.children.get(0);
		}else{
			if(this.pointer.parentNode == null){
				return null ;
			}else if(this.pointer.nextSibling() != null){
				this.pointer = this.pointer.nextSibling() ;
			}else{
				var parentNode = this.pointer.parentNode;
				var brother = parentNode.nextSibling() ;

				while(parentNode != null && brother == null){
					brother = parentNode.nextSibling();
					parentNode = parentNode.parentNode;
				}
				this.pointer = brother ;
			}

		}
	}
	return this.pointer ;
}

Tree.prototype.hasYoungerBrother = function(node){
	return node.nextSibling() != null ;
}

Tree.prototype.findParentNode = function(node){
	var size = this.nodes.size();
	for(var i=0; i<size; i++){
		var temp = this.nodes.get(i);
		if(temp.id == node.parentId){
			return temp ;
		}
	}
	return null ;
}

Tree.prototype.addNode = function(node){
	var parentNode = this.findParentNode(node);
	if(node.parentId == null || node.parentId == "" || parentNode == null){
		this.root.addChild(node);
	}else{
		parentNode.addChild(node);
	}
	this.nodes.add(node);
}

Tree.prototype.getDegree = function(){
	var degree = 0 ;
	for(var i=0;i<this.nodes.size();i++){
		if(this.nodes.get(i).rank > degree){
			degree = this.nodes.get(i).rank ;
		}
	}
	return degree ;
}

Tree.prototype.findNodeById = function(id){
	for(var i=0;i<this.nodes.size();i++){
		if(this.nodes.get(i).id == id){
			return this.nodes.get(i) ;
		}
	}
	return null ;
}

Tree.prototype.init = function(){
	this.root.refreshDegree();
	this.initSequence();
	this.initShadowIndex();
	this.initLines();
	this.neatened = true ;
}

Tree.prototype.initSequence = function(){
	this.pointer = null ;
	this.nodes.clear();
	var node = this.next();
	var index = 0 ;
	while(node != null){
		node.sequence = index++ ;
		node.refreshChapterNo();
		this.nodes.add(node);
		node = this.next() ;
	}
}

Tree.prototype.initShadowIndex = function(){
	var size = this.nodes.size();
	for(var i=0;i<size;i++){
		var node = this.nodes.get(i);
		node.shadowIndex = node.sequence ;
		for(var j=(node.sequence+1);j<size;j++){
			var temp = this.nodes.get(j);
			if(node.rank < temp.rank){
				node.shadowIndex = temp.sequence ;
			}else{
				break ;
			}
		}
	}	
}

Tree.prototype.initLines = function(){
	var size = this.nodes.size();
	for(var i=0;i<size;i++){
		var node = this.nodes.get(i);
		var line = this.hasYoungerBrother(node)?"1":"0";
		for(var j=node.sequence +1 ; j <= node.shadowIndex;j++){
			var temp = this.nodes.get(j);
			temp.lines[node.rank] = line ;
		}
	}
}

Tree.prototype.moveNodeUnder = function(nodeId,toId){
	var node = this.findNodeById(nodeId);
	var target = this.findNodeById(toId);
//	alert(node.name + " to "+ target.name);
	var parent = node.parentNode ;
	if(parent == null){
		alert("��ڵ㲻�����ƶ�");
		return ;
	}
	parent.removeChild(node);
	target.addChild(node);
}


function debug(info){
	var area = document.getElementById("areaDebug");
	area.value = area.value+"\r\n"+info;
}